package com.yms.jvm.invokedynamic;


import javax.tools.JavaCompiler;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

/**
 * @version : 1.0
 * @author: yangmingsong
 * @date: 2022/7/16-07-16-16:17
 * @description: spring5Test
 */
public class Test2 {

    public static void main(String[] args) {
//        强引用---无论任何情况下，只要强引用关系存在就不会被回收
        Father father1 = new Father();
//        软引用---当内存足够时不会被回收，当内存不足时会被回收
        SoftReference<Father> fatherSoftReference = new SoftReference<>(new Father());
        Father father = fatherSoftReference.get();
//        弱引用----只能生存到下一次垃圾回收--无论内存是否足够，当使用完后都会被回收
        WeakReference<Father> fatherWeakReference = new WeakReference<>(new Father());
        Father father2 = fatherWeakReference.get();
//        虚引用---虚灵引用，假引用--只是用来这个对象被回收时收到一个系统通知
        PhantomReference<Father> fatherPhantomReference = new PhantomReference<>(new Father(), new ReferenceQueue<Father>());
//        无法通过get获取到这个对象的实例
        Father father3 = fatherPhantomReference.get();
        System.out.println(father3);
        PhantomReference<Father> fatherPhantomReference1 = new PhantomReference<>(father1, new ReferenceQueue<>());
        boolean enqueue = fatherPhantomReference1.enqueue();
        System.out.println(fatherPhantomReference1.isEnqueued());
    }
}
class GrandFather{
    void thinking(){
        System.out.println("grandFather");
    }
}
class Father extends GrandFather{
    @Override
    void thinking() {
        System.out.println("father");
    }
}
class Son extends Father{
    @Override
    void thinking() {
        //new GrandFather().thinking();
//        装逼写法
        try {
        MethodType methodType = MethodType.methodType(void.class);
        Field impl_lookup = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
        impl_lookup.setAccessible(true);
        MethodHandle methodHandle = ((MethodHandles.Lookup) impl_lookup.get(null)).findSpecial(GrandFather.class, "thinking", methodType, GrandFather.class);
        methodHandle.invoke(this);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}